
#include "shader.h"
#include "window.h"
#include <map>

ADSShader shader;
Window window(1280, 800, &shader);

void DisplayFunc()
{
	glViewport(0, 0, window.width, window.height);
	glClearColor(1, 1, 1, 0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);

	window.Display();

	window.DisplayMode("Shaders");
	glutSwapBuffers();
}

void TimerFunc(int period)
{
	glutTimerFunc((unsigned int) period, TimerFunc, period);

	// Test the window handle before
	// calling   glutPostRedisplay()
	// because  the  window may have
	// closed while  we were asleep.
	// Without  this  test, we might
	// be posting  a message  for a
	// window that isn't there.
	if (window.window_handle != -1)
		glutPostRedisplay();
}

void ReshapeFunc(int w, int h)
{
	if (h == 0)
		return;
	window.width = w;
	window.height = h;
}

void SpecialFunc(int c, int x, int y)
{
	switch (c)
	{
	}
}

void KeyboardFunc(unsigned char c, int x, int y)
{
	switch (c)
	{
	case 27:
	case 'x':
		glutLeaveMainLoop();
		return;
	}
}

void CloseFunc()
{
	shader.TakeDown();
	// This  is  necessary to   prevent one
	// last execution of the timer function
	// from calling glutPostRedisplay after
	// the window has been closed.
	window.window_handle = (GLuint) -1;
}

float PI_over_2 = 3.14159265f / 2.0f;
float PI = 3.14159265f;

/*	These are simple functions which drive the creation of various surfaces of revolution.
*/

float CosWave(float t)
{
	float f = t;
	t = t * 2.0f * PI;
	float radius = cos(t) / 4.0f + 0.75f;
	return radius * f;
}

float HourGlass(float t)
{
	t = (2 * t - 1.0f) * PI_over_2;
	float radius = fabs(sin(t)) / 4.0f + 0.5f;
	return radius;
}

float Cone(float t)
{
	return t;
}

float InverseCone(float t)
{
	return 1.0f - t;
}

float TestCone(float t)
{
	return t / 2.0f;
}

float Cylinder(float t)
{
	return 0.5f;
}

/*	This method of creating a sphere does not sample the poles sufficiently densely. Therefore,
	a different means of sampling t should be used.
*/

float Sphere(float t)
{
	t = t - 0.5f;
	return sqrt(0.25f - t * t);
}

float Squiggle(float t)
{
	return t > 0.5f ? (t > 0.75f ? sin(t + PI) : cos(t + PI)) : sin(t - PI);
}

int main(int argc, char * argv[])
{
	glutInit(&argc , argv);
	ilInit();
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
	glutInitWindowPosition(0 , 0);
	glutInitWindowSize(window.width , window.height);
	window.window_handle = glutCreateWindow("Still Life");
	glutDisplayFunc(DisplayFunc);
	glutTimerFunc(1000 / 60, TimerFunc, 1000 / 60);
	glutReshapeFunc(ReshapeFunc);
	glutSpecialFunc(SpecialFunc);
	glutKeyboardFunc(KeyboardFunc);
	glutCloseFunc(CloseFunc);
	glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);

	if (glewInit() != GLEW_OK)
	{
		cerr << "GLEW failed to initialize." << endl;
		return 0;
	}

	WindowStruct mws;
	mws.grid_size = glm::ivec2(200, 200);
	mws.function = CosWave;
	mws.open = false;
	window.PostGLInitialize((void *) &mws);

	glutMainLoop();
	return 0;
}
